package christ.mmd;

import java.sql.Array;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import android.R.bool;
import android.os.Parcel;
import android.os.Parcelable;

import christ.mmd.bl.Community;
import christ.mmd.bl.Day;
import christ.mmd.bl.Event;
import christ.mmd.bl.Fast;
import christ.mmd.bl.FileUpdateInfo;
import christ.mmd.bl.Holiday;
import christ.mmd.bl.Region;
import christ.mmd.bl.reading.Reading;

public class DataProvider implements Parcelable {

	public boolean showSplashScreen = false;

	List<Day> mDayList;

	Hashtable<FileUpdateInfo.Type, FileUpdateInfo> mFileUpdateInfoHashTable = new Hashtable<FileUpdateInfo.Type, FileUpdateInfo>();
	Hashtable<Long, Community> mCommunityHashTable = new Hashtable<Long, Community>();
	Hashtable<Date, Hashtable<Reading.OfficeType, Reading>> mReadingsHashtable = new Hashtable<Date, Hashtable<Reading.OfficeType, Reading>>();
	Hashtable<Date, List<Holiday>> mHolidaysHashtable = new Hashtable<Date, List<Holiday>>();
	Hashtable<Region, List<Event>> mEventsHashtable = new Hashtable<Region, List<Event>>();
	Hashtable<Date, Fast> mFastsHashtable = new Hashtable<Date, Fast>();

	public DataProvider(Parcel in) {
		ArrayList<FileUpdateInfo> files = new ArrayList<FileUpdateInfo>();
		in.readList(files, getClass().getClassLoader());
		for (FileUpdateInfo fileUpdateInfo : files) {
			updateFileUpdateInfo(fileUpdateInfo);
		}

		ArrayList<Community> communities = new ArrayList<Community>();
		in.readList(communities, getClass().getClassLoader());
		updateCommunities(communities);
	}

	public DataProvider() {
	}

	public boolean isFileUpdateInfoNewer(FileUpdateInfo fileUpdateInfo) {
		boolean result = true;
		if (mFileUpdateInfoHashTable.containsKey(fileUpdateInfo.getType())) {
			FileUpdateInfo existing = mFileUpdateInfoHashTable
					.get(fileUpdateInfo.getType());
			if (fileUpdateInfo.getDate().compareTo(existing.getDate()) <= 0) {
				result = false;
			}
		}

		return result;
	}

	public void updateFileUpdateInfo(FileUpdateInfo fileUpdateInfo) {
		mFileUpdateInfoHashTable.put(fileUpdateInfo.getType(), fileUpdateInfo);
	}

	public void updateCommunities(List<Community> communities) {
		for (Community community : communities) {
			mCommunityHashTable.put(community.getId(), community);
		}
	}

	public void updateReading(Reading reading) {
		Date key = reading.getDate();
		if (!mReadingsHashtable.containsKey(key)) {
			mReadingsHashtable.put(key,
					new Hashtable<Reading.OfficeType, Reading>());
		}
		Hashtable<Reading.OfficeType, Reading> table = mReadingsHashtable
				.get(key);
		table.put(reading.getOfficeType(), reading);
	}

	public void updateHoliday(Holiday holiday) {
		Date key = holiday.getDate();
		if (!mHolidaysHashtable.containsKey(key)) {
			mHolidaysHashtable.put(key, new ArrayList<Holiday>());
		}
		List<Holiday> list = mHolidaysHashtable.get(key);
		list.add(holiday);
	}

	public Community[] getCommunities() {
		return mCommunityHashTable.values().toArray(new Community[0]);
	}

	@Override
	public int describeContents() {
		return 0;
	}

	@Override
	public void writeToParcel(Parcel dest, int flags) {
		dest.writeList(new ArrayList<FileUpdateInfo>(mFileUpdateInfoHashTable
				.values()));
		dest.writeList(new ArrayList<Community>(mCommunityHashTable.values()));
	}

	public static final Parcelable.Creator<DataProvider> CREATOR = new Parcelable.Creator<DataProvider>() {
		public DataProvider createFromParcel(Parcel in) {
			return new DataProvider(in);
		}

		public DataProvider[] newArray(int size) {
			return new DataProvider[size];
		}
	};

	public void updateReadings(List<Reading> readings) {
		for (Reading reading : readings) {
			updateReading(reading);
		}
	}

	public void updateHolidays(List<Holiday> holidays) {
		for (Holiday holiday : holidays) {
			updateHoliday(holiday);
		}
	}

	public void updateEvents(List<Event> events) {
		// TODO Auto-generated method stub
		for (Event event : events) {
			updateEvent(event);
		}
	}

	private void updateEvent(Event event) {
		ArrayList<Region> keys = event.getRegions();
		for (Region key : keys) {
			if (!mEventsHashtable.containsKey(key)) {
				mEventsHashtable.put(key, new ArrayList<Event>());
			}
			List<Event> list = mEventsHashtable.get(key);
			list.add(event);
		}
	}

	public void updateFasts(List<Fast> fasts) {
		// TODO Auto-generated method stub
		for (Fast fast : fasts) {
			updateFast(fast);
		}
	}

	private void updateFast(Fast fast) {
		Date dateBegin = fast.getDateBegin();
		Date dateEnd = fast.getDateEnd();
		if (dateBegin.equals(dateEnd)) {
			mFastsHashtable.put(dateBegin, fast);
		} else {
			Date date = dateBegin;
			while (!date.after(dateEnd)) {
				mFastsHashtable.put(date, fast);
				date = new Date(date.getTime() + 1000 * 60 * 60 * 24);
			}
		}
	}
}
